/**
 * FileName: DictValueServiceImpl
 * Author: zlz
 * CreatedDate: 2025/3/4 16:42:50
 * Description:
 * Version: 1.0.0
 */
package com.zlz.open.dict.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zlz.base.entity.response.ResultSet;
import com.zlz.base.enums.DefaultStatusEnum;
import com.zlz.base.enums.DeletedStatusEnum;
import com.zlz.base.exception.BizException;
import com.zlz.open.dict.bean.dos.DictGroupEntity;
import com.zlz.open.dict.bean.dos.DictValueEntity;
import com.zlz.open.dict.bean.request.DictValueRequest;
import com.zlz.open.dict.bean.transfer.DictTransfer;
import com.zlz.open.dict.bean.vo.DictValueResponse;
import com.zlz.open.dict.dao.DictValueDao;
import com.zlz.open.dict.service.DictGroupService;
import com.zlz.open.dict.service.DictValueService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zlz
 * @date 2025/3/4 16:42:50
 * @description
 */
@Service
public class DictValueServiceImpl implements DictValueService {

    private final DictGroupService dictGroupService;

    private final DictValueDao dictValueDao;

    public DictValueServiceImpl(DictGroupService dictGroupService, DictValueDao dictValueDao) {
        this.dictGroupService = dictGroupService;
        this.dictValueDao = dictValueDao;
    }

    @Override
    public Mono<ResultSet<Long>> save(Mono<DictValueRequest> request) {
        return request.flatMap(req -> {
            if (req.getValue() == null) {
                return Mono.error(new BizException("字典值不允许为空"));
            }
            if (req.getKey() == null) {
                return Mono.error(new BizException("字典值key不允许为空"));
            }
            if (req.getType() == null) {
                return Mono.error(new BizException("字典值类型不允许为空"));
            }
            DictValueEntity dictValue = dictValueDao.selectOne(Wrappers.<DictValueEntity>lambdaQuery()
                    .eq(DictValueEntity::getGroupCode, req.getGroupCode())
                    .eq(DictValueEntity::getKey, req.getKey())
                    .eq(DictValueEntity::getIsDeleted, DeletedStatusEnum.NOT_DELETED.getCode()));
            if (dictValue == null) {
                return createDictValue(Mono.just(req));
            }
            return updateDictValue(Mono.just(req));
        });
    }

    @Override
    public Mono<ResultSet<Long>> createDictValue(Mono<DictValueRequest> request) {
        return request.handle((req, sink) -> {
            if (req.getValue() == null) {
                sink.error(new BizException("字典值不允许为空"));
                return;
            }
            if (req.getKey() == null) {
                sink.error(new BizException("字典值key不允许为空"));
                return;
            }
            if (req.getType() == null) {
                sink.error(new BizException("字典值类型不允许为空"));
                return;
            }
            DictGroupEntity dictGroupEntity = dictGroupService.selectByCode(req.getGroupCode());

            DictValueEntity dictValueOld = dictValueDao.selectOne(Wrappers.<DictValueEntity>lambdaQuery()
                    .eq(DictValueEntity::getKey, req.getKey())
                    .eq(DictValueEntity::getGroupCode, dictGroupEntity.getCode()));
            if (dictValueOld != null && DeletedStatusEnum.DELETED.getCode().equals(dictValueOld.getIsDeleted())) {
                dictValueOld.setIsDeleted(DeletedStatusEnum.NOT_DELETED.getCode());
                dictValueDao.updateById(dictValueOld);
                sink.next(ResultSet.success(dictValueOld.getId()));
                return;
            }
            if (dictValueOld != null) {
                sink.error(new BizException(String.format("字典[%s],值[%s]已存在", dictValueOld.getGroupCode(), dictValueOld.getKey())));
                return;
            }

            DictValueEntity dictValueEntity = DictValueEntity.builder()
                    .key(req.getKey())
                    .value(req.getValue())
                    .type(req.getType())
                    .note(req.getNote())
                    .groupCode(dictGroupEntity.getCode()).build();
            int row = dictValueDao.insert(dictValueEntity);
            if (row != 1) {
                sink.error(new BizException("字段创建失败"));
                return;
            }
            sink.next(ResultSet.success(dictValueEntity.getId()));
        });
    }

    @Override
    public Mono<ResultSet<List<DictValueResponse>>> selectList(Mono<DictValueRequest> request) {
        return request.map(req -> {
            DictGroupEntity dictGroupEntity = dictGroupService.selectByCode(req.getGroupCode());
            LambdaQueryWrapper<DictValueEntity> queryWrapper = Wrappers.<DictValueEntity>lambdaQuery()
                    .eq(DictValueEntity::getGroupCode, dictGroupEntity.getCode()).orderByAsc(DictValueEntity::getCreatedTime);
            if (req.getIsDeleted() != null) {
                queryWrapper.eq(DictValueEntity::getIsDeleted, req.getIsDeleted());
            }
            if (req.getStatus() != null) {
                queryWrapper.eq(DictValueEntity::getStatus, req.getStatus());
            }
            if (StringUtils.isNotBlank(req.getKey())) {
                queryWrapper.eq(DictValueEntity::getKey, req.getKey());
            }
            if (StringUtils.isNotBlank(req.getValue())) {
                queryWrapper.eq(DictValueEntity::getValue, req.getValue());
            }
            if (StringUtils.isNotBlank(req.getType())) {
                queryWrapper.eq(DictValueEntity::getType, req.getType());
            }
            return ResultSet.success(
                    dictValueDao.selectList(queryWrapper).stream().map(DictTransfer::transfer).collect(Collectors.toList())
            );
        });

    }

    @Override
    public Mono<ResultSet<Long>> updateDictValue(Mono<DictValueRequest> request) {
        return request.<Integer>handle((req, sink) -> {
            if (StringUtils.isBlank(req.getKey()) || StringUtils.isBlank(req.getGroupCode())) {
                sink.error(new BizException("字典Code与key不允许为空"));
            }

            DictGroupEntity dictGroupEntity = dictGroupService.selectByCode(req.getGroupCode());
            DictValueEntity updateEntity = DictValueEntity.builder()
                    .key(req.getUpdateKey())
                    .value(req.getValue())
                    .type(req.getType())
                    .note(req.getNote())
                    .status(req.getStatus()).build();
            if (StringUtils.isNotBlank(req.getUpdateCode())) {
                try {
                    DictGroupEntity newGroup = dictGroupService.selectByCode(req.getUpdateCode());
                    updateEntity.setGroupCode(newGroup.getCode());
                } catch (Exception e) {
                    sink.error(new BizException("要修改的字典不存在"));
                    return;
                }
            }

            if (StringUtils.isNotBlank(req.getUpdateKey()) && !Objects.equals(req.getKey(), req.getUpdateKey())) {
                LambdaQueryWrapper<DictValueEntity> queryUpdateWrapper = Wrappers.<DictValueEntity>lambdaQuery()
                        .eq(DictValueEntity::getIsDeleted, DeletedStatusEnum.NOT_DELETED.getCode())
                        .eq(DictValueEntity::getGroupCode, dictGroupEntity.getCode())
                        .eq(DictValueEntity::getKey, req.getUpdateKey());

                Long count = dictValueDao.selectCount(queryUpdateWrapper);
                if (count != 0) {
                    sink.error(new BizException("要修改的key已经存在"));
                    return;
                }
            }

            LambdaQueryWrapper<DictValueEntity> queryWrapper = Wrappers.<DictValueEntity>lambdaQuery()
                    .eq(DictValueEntity::getIsDeleted, DeletedStatusEnum.NOT_DELETED.getCode())
                    .eq(DictValueEntity::getGroupCode, dictGroupEntity.getCode())
                    .eq(DictValueEntity::getKey, req.getKey());

            Long count = dictValueDao.selectCount(queryWrapper);
            if (count == 0) {
                sink.error(new BizException("无可操作的数据"));
                return;
            }

            LambdaUpdateWrapper<DictValueEntity> updateWrapper = Wrappers.<DictValueEntity>lambdaUpdate()
                    .eq(DictValueEntity::getGroupCode, dictGroupEntity.getCode())
                    .eq(DictValueEntity::getKey, req.getKey());

            int update = dictValueDao.update(updateEntity, updateWrapper);
            sink.next(update);
        }).map(row -> row > 0 ? ResultSet.success(Long.valueOf(row)) : ResultSet.error("更新失败"));
    }

    @Override
    public Mono<ResultSet<String>> deletedValue(Mono<DictValueRequest> request) {
        return request.filter(req -> StringUtils.isNotBlank(req.getGroupCode()))
                .switchIfEmpty(Mono.error(new BizException("编码不允许为空")))
                .handle((req, sink) -> {
                    DictGroupEntity groupEntity = dictGroupService.selectByCode(req.getGroupCode());
                    if (DefaultStatusEnum.DEFAULT.getCode().equals(groupEntity.getIsDefault())) {
                        sink.error(new BizException("默认字典不允许删除"));
                        return;
                    }
                    if (StringUtils.isNotBlank(req.getKey())) {
                        // 单条删除
                        DictValueEntity dictValue = dictValueDao.selectOne(Wrappers.<DictValueEntity>lambdaQuery()
                                .eq(DictValueEntity::getKey, req.getKey())
                                .eq(DictValueEntity::getGroupCode, groupEntity.getCode()));
                        if (dictValue == null) {
                            sink.error(new BizException("字典值不存在"));
                            return;
                        }
                        if (DeletedStatusEnum.DELETED.getCode().equals(dictValue.getIsDeleted())) {
                            sink.error(new BizException("字典值已经删除"));
                            return;
                        }
                        int row = dictValueDao.updateById(
                                DictValueEntity.builder()
                                        .id(dictValue.getId())
                                        .isDeleted(DeletedStatusEnum.DELETED.getCode())
                                        .build()
                        );
                        sink.next(
                                row > 0 ? ResultSet.success("删除成功") : ResultSet.error("删除失败")
                        );
                        return;
                    }
                    // 批量删除
                    int row = dictValueDao.update(
                            DictValueEntity.builder().isDeleted(DeletedStatusEnum.DELETED.getCode()).build(),
                            Wrappers.<DictValueEntity>lambdaUpdate().eq(DictValueEntity::getGroupCode, groupEntity.getCode())
                    );
                    sink.next(ResultSet.success(String.format("成功删除%s条数据", row)));
                });
    }
}
